package cn.chainco.cts.iserviceImpl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.chainco.cts.idao.IVerificationDao;
import cn.chainco.cts.idao.IWorkDao;
import cn.chainco.cts.iservice.IVerificationManager;
import cn.chainco.cts.jdo.Company;
import cn.chainco.cts.jdo.Employee;
import cn.chainco.cts.jdo.User;
import cn.chainco.cts.jdo.Verification;
import cn.chainco.cts.jdo.VerificationBill;
import cn.chainco.cts.jdo.Work;
import cn.chainco.cts.jdo.WorkFee;
import cn.chainco.cts.utils.TimeUtil;
import cn.chainco.cts.utils.query.OP;
import cn.chainco.cts.utils.query.QueryOrder;
import cn.chainco.cts.utils.query.QueryParam;
import cn.chainco.cts.jdo.Currency;
import cn.chainco.cts.jdo.ExcRate;

public class VerificationManagerImpl extends CommonManagerImpl implements IVerificationManager{
	private IVerificationDao verificationDao;
	private IWorkDao workDao;

	public void setWorkDao(IWorkDao workDao){
		this.workDao = workDao;
	}


	/**
	 * 获取某家公司指定创建天数某种类型的结算单的总数
	 */
	public int getCountByCompany(Company company, Date date,int type ){
		return this.verificationDao.getCountByCompany(company, date, type);
	}

	/**
	 * 验证订凭证号是否存在
	 */
	public boolean validateCardNum(long id,Company company, String cardNum,int type){
		return this.verificationDao.getVerificationBycardNum(id,company, cardNum, type)!=null;
	}

	/**
	 * 根据凭证号查询结算单
	 */
	public Verification getVerificationBycardNum(Company company, String cardNum,int type){
		return this.verificationDao.getVerificationBycardNum(0,company, cardNum, type);
	}

	/**
	 * 生成订凭证号
	 */
	public String getNewCardNum(Company company,int type){
		try {
			int count = this.getCountByCompany(company, new Date(),type);
			String cardNum= "";
			boolean isTrue = true;
			while(isTrue){
				count++;
				String index = count+"";
				if(count < 100) index = "0" + index;
				if(count < 10) index = "0" + index;
				cardNum = company.getPrefix()+TimeUtil.getYYYYMMDD(new Date()) + index;
				if(!this.validateCardNum(0,company, cardNum,type)){
					isTrue = false;
				}
			}
			return cardNum;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	// 根据时间获取汇率
	public float getExcRateByTime(Date delegateTime, long currencyId) {
		if (currencyId == Currency.CURRENCY_TYPE_CNY)
			return 1;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String time = format.format(delegateTime).substring(0, 10);
		List<QueryParam> queryParam = new ArrayList<QueryParam>();
		QueryParam param = new QueryParam();
		param.setField("effectiveDate");
		param.setOp(OP.lessEqual);
		try {
			param.setValue(new Object[] { format.parse(time) });
		} catch (ParseException e) {
			e.printStackTrace();
		}
		queryParam.add(param);

		QueryParam param3 = new QueryParam();
		param3.setField("currency.id");
		param3.setOp(OP.equal);
		param3.setValue(new Object[] { currencyId });
		queryParam.add(param3);

		List<QueryOrder> queryOrder = new ArrayList<QueryOrder>();
		QueryOrder order = new QueryOrder();
		order.setField("effectiveDate");
		order.setAscOrder(false);
		queryOrder.add(order);

		List<ExcRate> listExcRate = this.verificationDao.findByCustomized(ExcRate.class, queryParam, queryOrder);

		return listExcRate.get(0).getToRMB() / 100;
	}

	// 根据时间获取转换的汇率值
	public float getExcRateByTime(Date delegateTime, long sourceCurrenyId, long targetCurrenyId) {
		if (sourceCurrenyId == targetCurrenyId) {// 如果两者默认币种一样
			return 1;
		} else if (targetCurrenyId == Currency.CURRENCY_TYPE_CNY) {// 如果是目标是人民币,则返回sourceCurrenyId的人民币的汇率
			return 1 / getExcRateByTime(delegateTime, sourceCurrenyId);
		} else if (sourceCurrenyId == Currency.CURRENCY_TYPE_CNY) {// 如果是源来是人民币,则返回targetCurrenyId的人民币的汇率
			return getExcRateByTime(delegateTime, targetCurrenyId);
		} else {// 先把币种转成人民币，再转成公司币种
			float sourceCurrenyExchangeRate = getExcRateByTime(delegateTime, sourceCurrenyId);// sourceCurrenyId人民币比值
			float targetCurrenyExchangeRate2 = getExcRateByTime(delegateTime, targetCurrenyId);// targetCurrenyId币种的人民币比值
			return targetCurrenyExchangeRate2 / sourceCurrenyExchangeRate;
		}
	}
	
	/**
	 * 获取某家公司某种状态的结算单的数据
	 */
	public int getCountByCompany(Company company,int type){
		return this.verificationDao.getCountByCompany(company, type);
	}
	/**
	 * 获取某家公司某种状态的结算单币种分组金额 type=0为收入（收款） 1为 支出（付款） 2为奖励
	 */
	public List<Object> getMoneyByCompany(Company company,Employee employee,int type){
		return this.verificationDao.getMoneyByCompany(company,employee, type);
	}
	
	/**
	 * 获取某公司汇兑损益且根据币种分组
	 */
	public List<Object> getExchangeMoneyByCompany(Company company){
		return this.verificationDao.getExchangeMoneyByCompany(company);
	}
	/**
	 * 获取某公司银行手续费且根据币种分组
	 */
	public List<Object> getExchangeBlankMoneyByCompany(Company company,Employee employee){
		return this.verificationDao.getExchangeBlankMoneyByCompany(company,employee);
	}
	
	/**
	 * 根据结算单查询结算明细
	 */
	public List<VerificationBill> getVerificationBillByParent( long verificationId){
		List<QueryParam> queryParam = new ArrayList<QueryParam>();
		QueryParam param = new QueryParam();
		param.setField("verification.id");
		param.setOp(OP.equal);
		param.setValue( new Object[]{ verificationId } );
		queryParam.add( param );
		
		List<QueryOrder> queryOrder = new ArrayList<QueryOrder>();
		QueryOrder order = new QueryOrder();
		order.setField("verification.createTime");
		order.setAscOrder(false);
		queryOrder.add(order);
		
		return this.verificationDao.findByCustomized( VerificationBill.class, queryParam, queryOrder );
	}
	
	/***
	 * 根据某个委托方查询某公司底下的应收/应付/奖励款 type=1为应收，type=2为代收，type=3为应付，type=4为代付 type=5为奖励,searchTyps只有奖励的时候用到，格式为已归档的订单;应收已收的订单;应付已付的订单
	 */
	public List<WorkFee> getWorkFeeByCondition( Company company,Employee employee,int type,String workCode,String searchTyps){
		List<QueryParam> queryParam = new ArrayList<QueryParam>();
		QueryParam param = new QueryParam();
		param.setField("work.company");
		param.setOp(OP.equal);
		param.setValue( new Object[]{ company } );
		queryParam.add( param );
		
		if( type == 1 ){
			QueryParam param2 = new QueryParam();
			param2.setField("employee1");
			param2.setOp(OP.equal);
			param2.setValue( new Object[]{ employee } );
			queryParam.add( param2 );
			
			QueryParam param3 = new QueryParam();
			param3.setField("type");
			param3.setOp(OP.equal);
			param3.setValue( new Object[]{ 0 } );
			queryParam.add( param3 );
			
			QueryParam param4 = new QueryParam();
			param4.setField("(employeeId2 is null)");
			param4.setOp(OP.sql);
			param4.setValue( new Object[]{ } );
			queryParam.add( param4 );
			
		}else if( type == 2 ){
			QueryParam param2 = new QueryParam();
			param2.setField("employee2");
			param2.setOp(OP.equal);
			param2.setValue( new Object[]{ employee } );
			queryParam.add( param2 );
			
			QueryParam param3 = new QueryParam();
			param3.setField("type");
			param3.setOp(OP.equal);
			param3.setValue( new Object[]{ 0 } );
			queryParam.add( param3 );
		}else if( type == 3 ){
			QueryParam param2 = new QueryParam();
			param2.setField("employee1");
			param2.setOp(OP.equal);
			param2.setValue( new Object[]{ employee } );
			queryParam.add( param2 );
			
			QueryParam param3 = new QueryParam();
			param3.setField("type");
			param3.setOp(OP.equal);
			param3.setValue( new Object[]{ 1 } );
			queryParam.add( param3 );
			
			QueryParam param4 = new QueryParam();
			param4.setField("(employeeId2 is null)");
			param4.setOp(OP.sql);
			param4.setValue( new Object[]{ } );
			queryParam.add( param4 );
		}else if( type == 4 ){
			QueryParam param2 = new QueryParam();
			param2.setField("employee2");
			param2.setOp(OP.equal);
			param2.setValue( new Object[]{ employee } );
			queryParam.add( param2 );
			
			QueryParam param3 = new QueryParam();
			param3.setField("type");
			param3.setOp(OP.equal);
			param3.setValue( new Object[]{ 1 } );
			queryParam.add( param3 );
		}else if( type == 5 ){
			QueryParam param2 = new QueryParam();
			param2.setField("employee1");
			param2.setOp(OP.equal);
			param2.setValue( new Object[]{ employee } );
			queryParam.add( param2 );
			
			QueryParam param4 = new QueryParam();
			param4.setField("type");
			param4.setOp(OP.equal);
			param4.setValue( new Object[]{ 2 } );
			queryParam.add( param4 );
			
			if( searchTyps!=null ){
				String arr[] = searchTyps.split(";");
				if( arr[0].equals("1")){
					QueryParam param3 = new QueryParam();
					param3.setField("work.workingStatus");
					param3.setOp(OP.equal);
					param3.setValue( new Object[]{ 5 } );
					queryParam.add( param3 );
				}
				if( arr[1].equals("1")){
					QueryParam param_receive = new QueryParam();
					param_receive.setField("work.receiveVerifyStatus");
					param_receive.setOp(OP.notEqual);
					param_receive.setValue( new Object[]{ 1 } );
					queryParam.add( param_receive );
				}
				if( arr[2].equals("1")){
					QueryParam param_pay = new QueryParam();
					param_pay.setField("work.payVerifyStatus");
					param_pay.setOp(OP.notEqual);
					param_pay.setValue( new Object[]{ 1 } );
					queryParam.add( param_pay );
				}
			}
		}
		
		if( workCode!=null && workCode.trim().length()>0 ){
			QueryParam param5 = new QueryParam();
			param5.setField("work.workCode");
			param5.setOp(OP.like);
			param5.setValue( new Object[]{ "%"+workCode+"%" } );
			queryParam.add( param5 );
		}
		
		QueryParam param6 = new QueryParam();
		param6.setField("(money<>writtenOffmoney and notWrittenOffmoney!=0)");
		param6.setOp(OP.sql);
		param6.setValue( new Object[]{} );
		queryParam.add( param6 );
		List<QueryOrder> queryOrder = new ArrayList<QueryOrder>();
		QueryOrder order = new QueryOrder();
		order.setField("id");
		order.setAscOrder(false);
		queryOrder.add(order);
		List<WorkFee> list = this.verificationDao.findByCustomized( WorkFee.class, queryParam, queryOrder );
		return list;
	}


	/**
	 * 获取某人在某家公司的结算单的某种类别的总数
	 */
	public int getCountByStatus( Company company,User user,Employee employee,int type){
		return this.verificationDao.getCountByStatus(company, user,employee, type);
	}
	
	/***
	 * 列表查询
	 */
	public List<Verification> getVerificationByConditon( Company company,Employee employee,User user,String keyword,int dateType,int type,int pageSize,int pageNumber ){
		return this.verificationDao.getVerificationByConditon(company, employee, user, keyword, dateType, type, pageSize, pageNumber);
	}

	public void setVerificationDao(IVerificationDao verificationDao) {
		this.verificationDao = verificationDao;
	}
	
	/**
	 * 获取列表查询的总数
	 */
	public int getCountVerificationByConditon( Company company,Employee employee,User user,String keyword,int dateType,int type ){
		return verificationDao.getCountVerificationByConditon(company, employee, user, keyword, dateType, type);
	}
}
